home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-28 | 7.7 KB | 374 lines | [TEXT/CWIE] |
- /*
- File: LPushButton.cp
-
- Contains: AGA-savvy push button class.
-
- Copyright: ©1996 Chris K. Thomas. All Rights Reserved.
-
- Version: 1.0
- */
-
- #include "AGAColors.h"
- #include "LPushButton.h"
-
- #include <LStream.h>
- #include <UMemoryMgr.h>
-
- LPushButton*
- LPushButton::CreatePushButtonStream(LStream *inStream)
- {
- return new LPushButton(inStream);
- }
-
- LPushButton::LPushButton()
- {
- mTitle = ::NewHandle(0);
- ThrowIfMemError_();
- mPressed = false;
- }
-
-
- LPushButton::LPushButton(LStream *inStream)
- :LControl(inStream)
- {
- mPressed = false;
- mTitle = NULL;
-
- unsigned char size;
-
- inStream->ReadData(&size, 1);
-
- mTitle = ::NewHandle(size);
- ThrowIfMemError_();
-
- inStream->ReadData(*mTitle, size);
-
- OptimizeButtonSize();
- }
-
-
- LPushButton::~LPushButton()
- {
- if(mTitle)
- ::DisposeHandle(mTitle);
- }
-
- //
- // OptimizeButtonSize
- //
- // The AGA specifies 8 pixels between the text
- // and the edge of the button, on either side,
- // a total height of 20 pixels, and a text baseline
- // starting 6 pixels from the bottom.
- //
-
- void LPushButton::OptimizeButtonSize()
- {
- StHandleLocker stlock(mTitle);
-
- UInt16 width = ::TextWidth(*mTitle, 0, GetHandleSize(mTitle));
- UInt16 height = 20;
-
- width += (16 + 2); //remember that the edge is one pixel on either side
-
- ResizeFrameTo(width, height, false);
- }
-
- //
- // • Imaging ———————————————————————————————————————————————————————————————————————————————————
- //
-
-
- void
- LPushButton::DrawSelf()
- {
- Rect r;
-
- CalcLocalFrameRect(r);
-
- ::InsetRect(&r, -1, -1);
-
- if(IsEnabled())
- DrawOutline(r, &kBlackColor, &kColor12);
- else
- DrawOutline(r, &kColor7, &kColor7);
-
- DrawButtonBackground(r);
- DrawText(r);
- }
-
- void
- LPushButton::DrawText(const Rect &r)
- {
- if(!IsPressed())
- RGBForeColor(&kBlackColor);
- else
- RGBForeColor(&kWhiteColor);
-
- UInt16 width = TextWidth(*mTitle, 0, GetHandleSize(mTitle));
- UInt16 textCenter = width/2;
- UInt16 rectCenter = (r.right - r.left)/2;
-
- ::MoveTo(r.left + rectCenter - textCenter, r.bottom - 6);
- ::DrawText(*mTitle, 0, GetHandleSize(mTitle));
- }
-
- //
- // draw the 3D background
- //
-
- void LPushButton::DrawButtonBackground(const Rect &r)
- {
- const RGBColor *topleftdeepest;
- const RGBColor *topleftdeeper;
- const RGBColor *base;
- const RGBColor *bottomrightdeeper;
- const RGBColor *bottomrightdeepest;
- Rect workingRect;
-
- if(IsPressed())
- {
- topleftdeepest = &kColor11;
- topleftdeeper = &kColor10;
- base = &kColor9;
- bottomrightdeeper = &kColor8;
- bottomrightdeepest = &kColor7;
- }
- else
- {
- topleftdeepest = &kColor2;
- topleftdeeper = &kWhiteColor;
- base = &kColor2;
- bottomrightdeeper = &kColor5;
- bottomrightdeepest = &kColor8;
- }
-
- //
- // draw base
- //
- workingRect.left = r.left + 4;
- workingRect.top = r.top + 4;
- workingRect.right = r.right - 3;
- workingRect.bottom = r.bottom - 3;
-
- RGBForeColor(base);
- PaintRect(&workingRect);
-
- //
- // draw first ring (moving inward)
- //
-
- ::RGBForeColor(topleftdeepest); // left deepest line
- ::MoveTo(r.left + 2, r.top + 3);
- ::LineTo(r.left + 2, r.bottom - 3);
-
- ::MoveTo(r.left + 3, r.top + 2); // top deepest line
- ::LineTo(r.right - 3, r.top + 2);
-
- ::RGBForeColor(bottomrightdeepest); // left deepest line
-
- ::MoveTo(r.right - 2, r.top + 3); // right deepest line
- ::LineTo(r.right - 2, r.bottom - 3);
-
- ::MoveTo(r.left + 3, r.bottom - 2); // bottom deepest line
- ::LineTo(r.right - 3, r.bottom - 2);
-
- //
- // draw second ring (moving inward)
- //
-
- ::RGBForeColor(topleftdeeper); // left
- ::MoveTo(r.left + 3, r.top + 3);
- ::LineTo(r.left + 3, r.bottom - 3);
-
- ::MoveTo(r.left + 3, r.top + 3); // top
- ::LineTo(r.right - 3, r.top + 3);
-
- ::RGBForeColor(bottomrightdeeper);
- ::MoveTo(r.right - 3, r.top + 3); // right
- ::LineTo(r.right - 3, r.bottom - 3);
-
- ::MoveTo(r.left + 3, r.bottom - 3); // bottom
- ::LineTo(r.right - 3, r.bottom - 3);
-
- //
- // draw corners
- //
- if(IsPressed())
- {
- // top left
- SetCPixel(r.left + 3, r.top + 3, &kColor11);
- SetCPixel(r.left + 4, r.top + 4, &kColor10);
-
- // bottom left
- SetCPixel(r.left + 3, r.bottom - 3, &kColor9);
- SetCPixel(r.left + 3, r.bottom - 2, &kColor10);
-
- // top right
- SetCPixel(r.right - 3, r.top + 3, &kColor9);
- SetCPixel(r.right - 2, r.top + 3, &kColor8);
-
- // bottom right
- SetCPixel(r.right - 3, r.bottom - 3, &kColor7);
- SetCPixel(r.right - 4, r.bottom - 4, &kColor8);
- }
- else
- {
- // top left
- SetCPixel(r.left + 2, r.top + 3, &kColor4);
- SetCPixel(r.left + 3, r.top + 2, &kColor4);
- SetCPixel(r.left + 4, r.top + 4, &kWhiteColor);
-
-
- // bottom left
- SetCPixel(r.left + 2, r.bottom - 3, &kColor4);
- SetCPixel(r.left + 3, r.bottom - 2, &kColor4);
- SetCPixel(r.left + 3, r.bottom - 3, &kColor2);
-
- // top right
- SetCPixel(r.right - 3, r.top + 2, &kColor4);
- SetCPixel(r.right - 2, r.top + 3, &kColor5);
- SetCPixel(r.right - 3, r.top + 3, &kColor2);
-
- // bottom right
- SetCPixel(r.right - 3, r.bottom - 3, &kColor8);
- SetCPixel(r.right - 4, r.bottom - 4, &kColor5);
- }
- }
-
- //
- // draw the button outline
- //
-
- void LPushButton::DrawOutline( const Rect &r,
- const RGBColor *inOutlineColor,
- const RGBColor *inOutlineAliasColor)
- {
- RGBForeColor(inOutlineColor); // left side
- MoveTo(r.left + 1, r.top + 4);
- LineTo(r.left + 1, r.bottom - 4);
-
- MoveTo(r.right - 1, r.top + 4); // right side
- LineTo(r.right - 1, r.bottom - 4);
-
- MoveTo(r.left + 4, r.top + 1); // top
- LineTo(r.right - 4, r.top + 1);
-
- MoveTo(r.left + 4, r.bottom - 1); // bottom
- LineTo(r.right - 4, r.bottom - 1);
-
- //
- // corners ••• setcpixel isn’t very efficient
- //
-
- SetCPixel(r.left + 3, r.top + 1, inOutlineAliasColor); // top, left corner
- SetCPixel(r.left + 2, r.top + 2, inOutlineColor);
- SetCPixel(r.left + 1, r.top + 3, &kColor12);
-
- SetCPixel(r.left + 3, r.bottom - 1, inOutlineAliasColor); // bottom, left corner
- SetCPixel(r.left + 2, r.bottom - 2, inOutlineColor);
- SetCPixel(r.left + 1, r.bottom - 3, &kColor12);
-
- SetCPixel(r.right - 3, r.top + 1, inOutlineAliasColor); // top, right corner
- SetCPixel(r.right - 2, r.top + 2, inOutlineColor);
- SetCPixel(r.right - 1, r.top + 3, inOutlineAliasColor);
-
- SetCPixel(r.right - 3, r.bottom - 1, inOutlineAliasColor); // bottom, right corner
- SetCPixel(r.right - 2, r.bottom - 2, inOutlineColor);
- SetCPixel(r.right - 1, r.bottom - 3, inOutlineAliasColor);
- }
-
- //
- // • Mouse handling ————————————————————————————————————————————————————————————————————————————
- //
-
- void LPushButton::HotSpotAction(Int16 /*inHotSpot*/, Boolean inCurrInside, Boolean inPrevInside)
- {
- if(inPrevInside == false)
- {
- //
- // previously outside the button
- // currently inside the button
- //
- if(inCurrInside == true)
- {
- mPressed = true;
-
- Rect r;
-
- CalcLocalFrameRect(r);
- InsetRect(&r, -1, -1);
-
- DrawButtonBackground(r);
- DrawText(r);
- }
- }
- else
- {
- if(inCurrInside == false)
- {
- //
- // previously inside
- // currently outside
- //
-
- mPressed = false;
-
- Rect r;
-
- CalcLocalFrameRect(r);
- InsetRect(&r, -1, -1);
-
- DrawButtonBackground(r);
- DrawText(r);
- }
- }
- }
-
-
- void
- LPushButton::HotSpotResult(Int16 /*inHotSpot*/)
- {
- if(mPressed)
- {
- mPressed = false;
-
- Rect r;
- CalcLocalFrameRect(r);
- InsetRect(&r, -1, -1);
-
- DrawButtonBackground(r);
- DrawText(r);
- }
-
- BroadcastValueMessage();
- }
-
- //
- // • Title Accesors ————————————————————————————————————————————————————————————————————————————
- //
-
- StringPtr
- LPushButton::GetDescriptor(Str255 outDescriptor) const
- {
- StHandleLocker stlock(mTitle);
-
- outDescriptor[0] = GetHandleSize(mTitle);
- BlockMoveData(*mTitle, &outDescriptor[1], outDescriptor[0]);
-
- return NULL; //this is bad, but I'm not going to waste 255 bytes per button - what was GHD thinking??
- }
-
- void
- LPushButton::SetDescriptor(ConstStringPtr inDescriptor)
- {
- SetHandleSize(mTitle, inDescriptor[0]);
- ThrowIfMemError_();
-
- StHandleLocker stlock(mTitle);
-
- BlockMoveData(&inDescriptor[1], *mTitle, inDescriptor[0]);
-
- OptimizeButtonSize();
- }
-